package com.mswyt.utils.msLog;

import com.mswyt.utils.base.MsAopUtils;
import com.mswyt.utils.base.MsLogUtils;
import com.mswyt.utils.config.constants.ApplicationConstant;
import com.mswyt.utils.msLog.annotation.MsExecuteTime;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * @ClassName: MsExecuteTimeAop
 * @Description:
 */
@Slf4j
@Aspect
@Component
public class MsExecuteTimeAop {


    /**
     * 切入点
     */
    @Pointcut("@annotation(com.mswyt.utils.msLog.annotation.MsExecuteTime)) ")
    private void pointcut() {
    }

    @Around("pointcut()")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        //判断是否开启执行日志打印功能
        if (!"true".equals(ApplicationConstant.msLogOpenPrint)) return joinPoint.proceed();
        MsExecuteTime executeTimeA = MsAopUtils.getAnnotation(joinPoint, MsExecuteTime.class);
        if (executeTimeA == null) return joinPoint.proceed();
        Object res = null;
        long bTime = System.currentTimeMillis();
        boolean error = false;
        try {
            res = joinPoint.proceed();//调用目标方法  返回目标方法的返回结果
        } catch (Throwable e) {
            error = true;
            e.printStackTrace();
        } finally {
            String logName = MsAopUtils.getClass(joinPoint).getSimpleName() + "." + MsAopUtils.getMethod(joinPoint).getName();
            long eTime = System.currentTimeMillis();
            long exTime = eTime - bTime;
            if (executeTimeA.limit() == -1 || exTime >= executeTimeA.limit()) {
                String infos = "线程{} , 调用{}(...)方法 , 耗时{}/ms , 备注:{}";
                Object[] args = {Thread.currentThread().getName(), logName, (exTime) / 1000, executeTimeA.msg()};
                if (error) {
                    MsLogUtils.error(infos, args);
                } else {
                    MsLogUtils.info(infos, args);
                }
            }
        }
        return res;

    }
}
